package com.mgq.java8.lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.*;

/**
 * <b>功能：</b>LambdaTest<br>
 * <b>Copyright mgq</b>
 * <li>版本&nbsp;&nbsp;&nbsp;&nbsp;修改日期&nbsp;&nbsp;&nbsp;&nbsp;部　　门&nbsp;&nbsp;&nbsp;&nbsp;作　者&nbsp;&nbsp;&nbsp;&nbsp;变更内容</li><hr>
 * <li>v1.0&nbsp;&nbsp;&nbsp;&nbsp;20220326&nbsp;&nbsp;营业后台&nbsp;&nbsp;&nbsp;&nbsp;马广奇&nbsp;&nbsp;&nbsp;&nbsp;创建类</li>
 * <br><br>
 *
 * @author 马广奇
 * @version 2022-03-26 15:49
 */
public class LambdaTest {
    public static void main(String[] args) {
        List<Apple> list = Arrays.asList(new Apple("green", 100), new Apple("red", 160),
                new Apple("green", 155), new Apple("red", 101));
        List<Apple> apples = Apple.filterGreenAndWeight(list, (color, weight) -> "green".equalsIgnoreCase(color) && weight > 150);
        //apples.forEach(System.out::println);
        //functionInterface(1, "2");
        test4();
    }

    public static void lambdaExample() {
        //1. 布尔表达式
        // (List<String> list) -> list.isEmpty();
        //2.创建对象
        //() -> new Apple("red",230l);
        //3.消费一个对象
        /*(Apple a) -> {
            System.out.println(a.getWeight());
        }*/
        //4.从一个对象中选择/抽取
        // (String s) -> s.length()
        //5.组合2个对象
        // (a,b)->a*b
        //6.比较2个对象
        /*(Apple a1, Apple a2) ->
            a1.getWeight().compareTo(a2.getWeight())
        */
    }

    /**
     * 谓词复合 predicted
     */
    public static void test3() {
        Predicate<Apple> redApple = (apple) -> apple.getColor().equals("red");
        //产生非  不是红苹果
        Predicate<Apple> notRedApple = redApple.negate();
        //并且重量大于150
        Predicate<Apple> notRedAppleHeavyApple = notRedApple.and(apple -> apple.getWeight() > 150);
        //要么重于150g的红苹果,要么绿苹果
        Predicate<Apple> redOrGreenApple = redApple.and(apple -> apple.getWeight() > 150).or(apple -> "green".equals(apple.getColor()));

    }

    /**
     * 函数复合
     */
    public static void test4() {
        Function<Integer, Integer> f = x -> x + 1;
        Function<Integer, Integer> g = x -> x * 2;
        Function<Integer, Integer> h = f.andThen(g);
        Integer result = h.apply(1);//答案是4 g(f(x))
        System.out.println(result);
        Function<Integer, Integer> y = f.compose(g);
        Integer apply = y.apply(1);
        System.out.println(apply);//答案是3 f(g(x))
        //另外一个例子
        Function<String, String> addHeader = Letter::addHeader;
        Function<String, String> transformationPipeLine = addHeader.andThen(Letter::checkSpell).andThen(Letter::addFoot);
        Function<String, String> transformationPipeLine2 = addHeader.compose(Letter::checkSpell).compose(Letter::addFoot);
        System.out.println(transformationPipeLine.apply("hello world"));
        System.out.println(transformationPipeLine2.apply("hello world"));

    }

    public static <R> void functionInterface(R r) {
        //predicate 接口
        System.out.println("------------------------------");
        Predicate<List<String>> predicate = (List<String> list1) -> list1.isEmpty();
        System.out.println(predicate.test(new ArrayList<>()));
        System.out.println("------------------------------");
        //consumer 接口
        Consumer<String> consumer = s -> System.out.println(s);
        consumer.accept("我是consumer");

        System.out.println("------------------------------");
        //Function接口
        Function<String, Integer> function = (s -> s.length());
        Integer length = function.apply("hello");
        System.out.println("长度是:" + length);
        BiFunction<String, Integer, Apple> biFunction = Apple::new;
        biFunction.apply("blue", 20);
        System.out.println("------------------------------");
        //Supplier接口
        Supplier<Apple> supplier = () -> new Apple("blue", 100);
        System.out.println(supplier.get());
        System.out.println("------------------------------");
        //IntPredicate
        IntPredicate intPredicate = (i) -> i % 2 == 0;
        System.out.println(intPredicate.test(100));
        System.out.println("------------------------------");
        //LongPredicate,DoublePredicate类似
        LongPredicate longPredicate = (l) -> l % 2 != 0;
        System.out.println(longPredicate.test(1000L));
        System.out.println("------------------------------");
        //IntConsumer,LongConsumer,DoubleConsumer
        IntConsumer intConsumer = a -> System.out.println(a);
        intConsumer.accept(10);
        System.out.println("------------------------------");
        //IntFunction<R>,LongFunction<R>,
        IntFunction<String> intFunction = i -> "" + i;
        IntFunction<R> intFunction1 = i -> (R) ("" + i);
        System.out.println(intFunction.apply(100));
        System.out.println(intFunction1.apply(1001));
        System.out.println("------------------------------");
        //IntToLongFunction
        IntToLongFunction intToLongFunction = i -> i;
        System.out.println(intToLongFunction.applyAsLong(20));
        System.out.println("------------------------------");
        //BinaryOperator<T> 二元运算法(比如加法,乘法)
        BinaryOperator<Integer> binaryOperator = (a, b) -> Integer.sum(a, b);
        System.out.println(binaryOperator.apply(2, 3));

        int port = 2;
        Runnable runnable = () -> System.out.println(port);

    }

    private int j = 22;

    private void test() {
        int i = 20;
        Consumer consumer = (x) -> {
            System.out.println(x);
            System.out.println(i);
            System.out.println(j);
        };
    }
}
